#include<iostream>
#include<vector>
#include<cstdio>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
using namespace std;

vector<int> data;

enum{
    OK = 0,
    OPEN_FILE_ERROR,
};

int SaveBegin()
{
    string name = to_string(time(nullptr));//将时间戳组成的整型转化为字符串
    name += ".backup";
    FILE *fp = fopen(name.c_str(),"w");//要注意把文件名转为c风格的字符串
    if(fp == nullptr) return OPEN_FILE_ERROR;

    string datastr;
    for(auto e : data)
    {
        datastr += to_string(e);
        datastr += " ";
    }
    fputs(datastr.c_str(), fp);
    fclose(fp);
    return OK;
}

void save()
{
    pid_t id = fork();
    if(id == 0)
    {
        //子进程，进行备份
        int code = SaveBegin();
        exit(code);//获得子进程的退出码
    }
    int status = 0;
    //&status用于存储子进程的退出状态，是一个指向整数的指针
    //第三个参数默认为0，即为阻塞等待
    pid_t rid = waitpid(id, &status, 0);//等待子进程完成。成功则返回子进程的PID，失败则返回-1
    if(rid > 0)//等待成功
    {
        int code = WEXITSTATUS(status);//提取子进程退出码
        if(code == 0) printf("备份成功，退出码为：%d\n",code);
        else printf("备份失败，退出码为：%d\n",code);
    }
    else{
        perror("waitpid");
    }
}


//int main()
//{
//    int cnt = 1;
//    while(true)
//    {
//        data.push_back(cnt++);
//        sleep(1);
//        if(cnt % 10 == 0)//每隔10秒就把数据备份一次
//            save();
//    }
//    return 0;
//}
//
//

#include<functional>

void PrintLog()
{
    printf("PrintLog task\n");
}

void DownLoad()
{
    printf("DownLoad task\n");
}

void BackUp()
{
    printf("BackUp task\n");
}

typedef function<void()> task_t;

void LoadTask(vector<task_t> &tasks)
{
    tasks.push_back(PrintLog);
    tasks.push_back(DownLoad);
    tasks.push_back(BackUp);
}

int main()
{
    vector<task_t> tasks;
    LoadTask(tasks);
    pid_t id = fork();
    if(id == 0)
    {
        //子进程
        while(true)
        {
            printf("我是子进程，我的PID是：%d\n",getpid());
            sleep(1);
        }
        exit(1);
    }

    //父进程
    while(true)
    {
        sleep(1);
        pid_t rid = waitpid(id, nullptr, WNOHANG);//父进程非阻塞方式等待子进程结束，如果子进程一直没有结束，则父进程一直做自己的事情
        if(rid > 0)
        {
            printf("等待子进程成功。\n");
            break;
        }
        else if(rid < 0)
        {
            printf("等待失败。\n");
            break;
        }
        else{
            printf("子进程尚未退出。\n");
            //做自己的事情
            for(auto &task : tasks)
            {
                task();
            }
        }
    }
}
